#include "Geo.h"

float Segment::Distance( const Vec& p ) const
{
	const Vec& v = Start;
	const Vec& w = End;

	const float l2 = (w-v).LengthSquared();  // i.e. |w-v|^2 -  avoid a sqrt
	if (l2 == 0.0f) return (p-v).Length();   // v == w case

	const float t = (p - v).DotProduct(w - v) / l2;
	if (t < 0.0f) return (p-v).Length();
	else if (t > 1.0f) return (p-w).Length();

	const Vec projection = v + (w - v) * t;  // Projection falls on the segment
	return (p-projection).Length();
}

float Segment::AsLineDistance( const Vec& p ) const
{
	float ldx = End.X-Start.X; // dx for line
	float ldy = End.Y-Start.Y; // dy for line
	return fabs( ldx * (Start.Y - p.Y) - (Start.X - p.X) * ldy ) / sqrtf( ldx * ldx + ldy * ldy );
}

Vec Segment::Bounce( const Vec& p ) const
{
	Vec n = (End-Start).Normalized();

	return Start*2.0f - p + n*2.0f*(p-Start).DotProduct(n);
}